<template>
    <div class="page_root" :key="queryUpdateFlag" data-page-name="faq问题" data-page-identification="g_fg9mt2lh8c">
        <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip">
            <!-- begin vid_bdcd4dofka 自定义模板_da85dlu48q -->
            <!--            回答-->
            <a-modal
                :visible="state.answerVisible"
                title="回答"
                centered
                :mask-closable="false"
                @ok="handleConfirmAnswer"
                @cancel="cancelAnswer"
                width="1000px"
                destroy-on-close
                :ok-button-props="{ loading: state.answerLoading }"
            >
                <div class="add-or-edit-faq">
                    <a-form :model="state.answerForm" ref="answerRef">
                        <a-row>
                            <a-col :span="24">
                                <a-form-item
                                    label=""
                                    :rules="[{ required: true, message: '请输入回答', trigger: 'blur' }]"
                                    name="answer"
                                >
                                    <!--                                    <a-textarea-->
                                    <!--                                        placeholder="请输入回答"-->
                                    <!--                                        show-count-->
                                    <!--                                        :rows="2"-->
                                    <!--                                        v-model:value="state.answerForm.answer"-->
                                    <!--                                    />-->
                                    <QuillEditor
                                        v-model:content="state.answerForm.answer"
                                        ref="quillEditor"
                                        :options="editorOption"
                                        class="quill-editor"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                    </a-form>
                </div>
            </a-modal>
            <!--            回答-->
            <!--            新建/编辑FAQ-->
            <a-modal
                :visible="state.addOrEditFaqVisible"
                :title="state.addOrEditTitle"
                centered
                :mask-closable="false"
                @ok="handleConfirmFaq"
                @cancel="cancelAdd"
                width="1000px"
                destroy-on-close
                :ok-button-props="{ loading: state.addLoading }"
            >
                <div class="add-or-edit-faq">
                    <a-form :model="state.modalForm" ref="faqRef">
                        <a-row>
                            <!--                            <a-col :span="24">-->
                            <!--                                <a-form-item-->
                            <!--                                    label="情景"-->
                            <!--                                    :rules="[{ required: true, message: '请输入情景', trigger: 'blur' }]"-->
                            <!--                                    name="scene"-->
                            <!--                                >-->
                            <!--                                    <a-textarea :rows="2" v-model:value="state.modalForm.scene" />-->
                            <!--                                </a-form-item>-->
                            <!--                            </a-col>-->
                            <a-col :span="24">
                                <a-form-item
                                    label="问题名称"
                                    :rules="[{ required: true, message: '请输入问题名称', trigger: 'blur' }]"
                                    name="problemName"
                                >
                                    <a-textarea
                                        show-count
                                        :maxlength="100"
                                        :rows="2"
                                        v-model:value="state.modalForm.problemName"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item
                                    label="项目阶段"
                                    :rules="[{ required: true, message: '请输入项目阶段', trigger: 'blur' }]"
                                    name="stageNames"
                                >
                                    <a-textarea
                                        placeholder="请输入，不同项目阶段根据“;”区分"
                                        show-count
                                        :rows="2"
                                        v-model:value="state.modalForm.stageNames"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item
                                    label="标签"
                                    :rules="[{ required: true, message: '请输入标签', trigger: 'blur' }]"
                                    name="labels"
                                >
                                    <a-textarea
                                        placeholder="请输入，不同标签根据“;”区分"
                                        show-count
                                        :rows="2"
                                        v-model:value="state.modalForm.labels"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                    </a-form>
                </div>
            </a-modal>
            <!--            新建/编辑FAQ-->
            <a-spin :spinning="state.dataloading" tip="加载中">
                <div class="body" :style="getBodyStyle()">
                    <a-row :gutter="24">
                        <a-col :span="6">
                            <a-form-item label="关键字">
                                <a-input
                                    placeholder="请输入关键字或标签检索"
                                    v-model:value="state.keyWords"
                                    @input="debouncedGetData"
                                />
                            </a-form-item>
                        </a-col>
                        <a-col :span="2">
                            <a-button @click="resetData" type="primary" ghost>重置</a-button>
                        </a-col>
                        <!-- end vid_hwx83rvzpu 我的 -->
                        <!-- begin vid_eaymhbrupq 审批 -->
                        <a-col :span="2" offset="14" style="display: flex; justify-content: end">
                            <a-button type="primary" @click="handleAddFaq" v-permission="'3000001016_vid_0qeikpreii'">
                                <template #icon><PlusOutlined /></template>
                                新建
                            </a-button>
                        </a-col>
                    </a-row>
                    <div class="gd-template-scroll">
                        <template v-if="state.dataList.length == 0">
                            <div class="no-data-img"></div>
                            <div class="no-data-msg">暂无数据</div>
                        </template>
                        <div class="gd-item" v-for="(item, index) in state.dataList" :key="item.id">
                            <div class="template-item-title">
                                <div class="item-left">
                                    <div class="item-top">
                                        <div class="top-left-div">
                                            <div class="item-name" @click="jumpDetail(item.id)">
                                                <div class="count">{{ index + 1 }} <div class="count-under"></div> </div
                                                >{{ item.problemName }}</div
                                            >
                                        </div>
                                    </div>
                                </div>
                                <div class="tem-right">
                                    <div class="top-right-div" @click.stop="onClick">
                                        <a-space :size="8">
                                            <a-button
                                                type="primary"
                                                ghost
                                                size="small"
                                                class="btn-item"
                                                v-permission="'3000001016_vid_f3635cbyfy'"
                                                @click="handleShowAnswer(item)"
                                                >回答
                                            </a-button>

                                            <a-button
                                                type="primary"
                                                ghost
                                                size="small"
                                                class="btn-item"
                                                @click="handlEditFaq(item)"
                                                v-permission="'3000001016_vid_qpqhaunz1y'"
                                                :disabled="!item.operateFlag"
                                                >编辑
                                            </a-button>
                                            <a-popconfirm
                                                title="确认删除吗?"
                                                ok-text="确定"
                                                cancel-text="取消"
                                                :disabled="!item.operateFlag"
                                                @confirm="handleConfirmDelete(item.id)"
                                                @cancel="cancel"
                                            >
                                                <a-button
                                                    :disabled="!item.operateFlag"
                                                    type="primary"
                                                    ghost
                                                    v-permission="'3000001016_vid_i9qutm9s24'"
                                                    size="small"
                                                    >删除</a-button
                                                >
                                            </a-popconfirm>
                                            <a-button type="primary" v-permission="'3000001016_vid_zvzhxtmham'" ghost size="small" @click="jumpDetail(item.id)"
                                                >详情</a-button
                                            >
                                        </a-space>
                                    </div>
                                </div>
                            </div>
                            <div class="icon-main">
                                <div class="item-icon">
                                    <a-tag
                                        style="color: #52c41a"
                                        v-for="(tag, index) in item.labelList"
                                        :key="'label-' + index"
                                        :color="colorList[0]"
                                        :bordered="false"
                                    >
                                        {{ tag }}
                                    </a-tag>

                                    <!-- stageNameList 标签，使用 colorList[1] -->
                                    <a-tag
                                        style="color: #fa8c16"
                                        v-for="(tag, index) in item.stageNameList"
                                        :key="'stage-' + index"
                                        :color="colorList[1]"
                                        :bordered="false"
                                    >
                                        {{ tag }}
                                    </a-tag>
                                </div>
                                <div class="item-bottom">
                                    <div class="bottom-top-item">
                                        <span class="bottom-top-title">创建人：</span>
                                        <span class="bottom-top-msg">{{ item.createdBy }}</span></div
                                    >
                                    <div class="bottom-top-item">
                                        <span class="bottom-top-title">创建时间：</span>
                                        <span class="bottom-top-msg">{{ item.createdTime }}</span></div
                                    >
                                </div>
                            </div>

                            <div class="answer-item" v-if="item.answer" :key="index">
                                <div class="btn-title">
                                    <div class="btn-left">
                                        <div class="btn-img"></div>
                                        <div class="btn-name">置顶回答</div>
                                    </div>
                                    <a-space>
                                        <a-button
                                            style="padding: 0"
                                            type="link"
                                            size="small"
                                            @click="changeStatus(item.answer, index)"
                                            :disabled="!item.answer.operateFlag"
                                            :loading="item.answer.loading"
                                            v-permission="'3000001016_vid_230y7a3epu'"
                                            >{{ item.answer.display ? '取消置顶' : '增加置顶' }}</a-button
                                        >
                                        <div class="line"    v-permission="'3000001016_vid_230y7a3epu'"></div>
                                        <a-button
                                            style="padding: 0"
                                            type="link"
                                            size="small"
                                            @click="handleEditAnswer(item.answer, index)"
                                            v-permission="'3000001016_vid_qpqhaunz1y'"
                                            :disabled="!item.answer.operateFlag"
                                            >编辑</a-button
                                        >
                                        <div class="line"       v-permission="'3000001016_vid_qpqhaunz1y'"></div>
                                        <a-popconfirm
                                            title="确认删除这条回答吗?"
                                            ok-text="确定"
                                            cancel-text="取消"
                                            :disabled="!item.answer.operateFlag"
                                            @confirm="handleConfirmDeleteAnswer(item.answer.id)"
                                            @cancel="cancel"
                                        >
                                            <a-button
                                                style="padding: 0"
                                                type="link"
                                                v-permission="'3000001016_vid_i9qutm9s24'"
                                                :disabled="!item.answer.operateFlag"
                                                size="small"
                                                >删除</a-button
                                            >
                                        </a-popconfirm>
                                        <a-button
                                            style="padding: 0"
                                            type="link"
                                            size="small"
                                            @click="toggleExpand(index)"
                                        >
                                            {{ expandedIndex === index ? '收起' : '阅读全文'
                                            }}<UpOutlined v-if="expandedIndex === index" /> <DownOutlined v-else />
                                        </a-button>
                                    </a-space>
                                </div>
                                <div class="answer-content">
                                    <div
                                        class="answer-preview"
                                        :class="{ expanded: expandedIndex === index }"
                                        v-html="getHtmlContent(item.answer.answer)"
                                    ></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </a-spin>
            <!-- end vid_bdcd4dofka 自定义模板_da85dlu48q -->
            <!--            <div class="pagination-div">-->
            <!--                <a-pagination-->
            <!--                    v-model:current="pagination.current"-->
            <!--                    :total="pagination.total"-->
            <!--                    :show-total="pagination.showTotal"-->
            <!--                    :page-size="pagination.pageSize"-->
            <!--                    show-quick-jumper-->
            <!--                    @show-size-change="pageSizeChange"-->
            <!--                    @change="pageChange"-->
            <!--                />-->
            <!--            </div>-->
        </a-spin>
    </div>
</template>
<script setup lang="tsx">
    import {
        h,
        ref,
        reactive,
        toRaw,
        markRaw,
        watch,
        computed,
        onBeforeMount,
        onMounted,
        onBeforeUnmount,
        onUnmounted,
        onActivated,
        onDeactivated,
        nextTick
    } from 'vue'
    import { useRoute, useRouter } from 'vue-router'
    const router = useRouter()
    const route = useRoute()
    import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios'
    import {
        cloneDeep,
        localGet,
        merge,
        getDifferenceArray,
        traversalTreeStructure,
        checkCaseCondition,
        renderStringInTemplate,
        handleBreadcrumbJump,
        throttle,
        permission,
        getComponentParamsValue
    } from '@/utils/index'
    import { isNullOrEmpty, isEmptyArr, isNullOrUnDef, isContained, isArray, isEmpty, isObject } from '@/utils/is'
    import dayjs from 'dayjs'
    import { getPagePcChartsDataSourceConvert } from '@/utils/chart'
    import { message, notification, Modal } from 'ant-design-vue'
    import {
        propertyFormatByNumber,
        propertyFormatByPercentage,
        propertyFormatByDate,
        parseSubFromDataList
    } from '@/utils/format'
    import colorTheme from '@/design/custom-theme.json'
    /*** PUBLISH_EXEGESIS ***
 import UserTableRecords from '@/model/UserTableRecords';
 import { getAppBaseUrl } from '@/utils/index';
 import { sendToken } from "@/hooks/useIframeToken";
 import { useSystemStore } from "@/store/modules/system";
 const systemStore = useSystemStore();
 *** PUBLISH_EXEGESIS ***/

    // 获取传入的流程ID和组件参数
    const props = defineProps({
        'processInstanceId': {
            type: [String, Number, Boolean],
            default: undefined
        }
    })
    const immediateWatch = (source, callback) => {
        watch(source, callback, { deep: true, immediate: true })
    }

    /* -------------------------- 属性定义 -------------------------- */

    const setTimeOutList = []
    const pageLoading = reactive({
        loading: false,
        tip: undefined
    })
    const authInfo = localGet('app-user-store')

    // 处理校验
    const setSubFormName = (parentInfo, name) => {
        return [parentInfo.parents, parentInfo.cycleIndex, name]
    }

    /* ========================== 属性定义 ========================== */

    /* -------------------------- 元素数据引用 -------------------------- */

    /* ========================== 元素数据引用 ========================== */

    /* -------------------------- 页面数据 -------------------------- */

    /* ========================== 页面数据 ========================== */

    /* -------------------------- 响应 -------------------------- */

    /* ========================== 响应 ========================== */

    /* -------------------------- 函数 -------------------------- */

    /* ========================== 函数 ========================== */

    /* -------------------------- 页面参数 -------------------------- */

    const pageParameter_state = reactive({
        'processInstanceId': props.processInstanceId ?? route.query.processInstanceId
    })

    /* ========================== 页面参数 ========================== */

    /* -------------------------- 组件事件处理方法 -------------------------- */

    // ---------------------------- 组件数据同步 ----------------------------

    // ============================ 组件数据同步 ============================

    /* ========================== 组件事件处理方法 ========================== */

    /* -------------------------- 生命周期 -------------------------- */
    // 用于参数变更后重新执行自定义指令
    const queryUpdateFlag = ref(0)
    onMounted(() => {})

    onUnmounted(() => {
        // 销毁定时器
        setTimeOutList.forEach(({ repeat, timer }) => {
            repeat ? clearInterval(timer) : clearTimeout(timer)
        })
    })

    /* ========================== 生命周期 ========================== */

    /* -------------------------- 数据关联处理 -------------------------- */

    /* -------------------------- 表单数据同步 -------------------------- */
    /* ========================== 表单数据同步 ========================== */

    /* ========================== 数据关联处理 ========================== */

    /* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */

    /* ========================== 不同组件自定义的处理逻辑 ========================== */

    // ================================定制化逻辑========================================
    onMounted(() => {
        const urlParams = new URLSearchParams(window.location.search)
        if (urlParams) {
            // 获取单个参数
            state.detailId = urlParams?.get('id')
            state.from = urlParams?.get('from')
        }
        getData()
        document.addEventListener('click', e => {
            const target = e.target as HTMLElement
            if (target.tagName === 'IMG' && target.classList.contains('previewable-image')) {
                const imgUrl = target.getAttribute('src')
                if (imgUrl) {
                    // 预览逻辑，如弹窗显示 imgUrl
                    previewImage(imgUrl)
                }
            }
        })
    })
    function previewImage(url) {
        const imgWindow = window.open()
        if (imgWindow) {
            imgWindow.document.write(`<img src="${url}" style="max-width:100%"/>`)
        }
    }
    const state = reactive({
        keyWords: undefined,
        id: undefined,
        detailId: undefined,
        from: undefined,
        dataList: [],
        answerVisible: false,
        addOrEditFaqVisible: false,
        modalForm: {
            'problemName': undefined,
            'scene': undefined,
            'stageNames': undefined,
            'labels': undefined
        },
        dataLoading: false,
        addLoading: false,
        answerLoading: false,
        answerForm: {
            answer: undefined
        },
        addOrEditTitle: ''
    })
    const colorList = ['#EDF9E8', '#FEF3E7 ', 'orange']
    function debounce(fn, delay = 300) {
        let timer = null
        return function (...args) {
            if (timer) clearTimeout(timer)
            timer = setTimeout(() => {
                fn.apply(this, args)
            }, delay)
        }
    }

    const debouncedGetData = debounce(getData, 300)
    function getData() {
        state.dataloading = true
        post(`/solution-ppm/api/v2/built-in-system-ppm/qa/question/search`, {
            keywords: state.keyWords,
            stageNames: state.detailId
            // pageNo:pagination.value.current,
            // pageSize:pagination.value.pageSize
        })
            .then(data => {
                if (data.code !== 200) {
                    state.dataList = []
                    message.error(data.message)
                    return
                }
                state.dataList = data.data
                // state.dataList = data.data.content
                // pagination.value.total = data.data.totalElements
            })
            .finally(() => {
                state.dataloading = false
            })
    }
    function resetData() {
        state.keyWords = undefined
        getData()
    }
    function jumpDetail(id) {
        window.open(`${import.meta.env.VITE_PUBLIC_PATH}/page/3000001017?id=${id}`, '_blank')
    }
    function handleAddFaq() {
        state.addOrEditTitle = '新建FAQ'
        state.addOrEditFaqVisible = true
    }
    function cancelAdd() {
        state.addOrEditFaqVisible = false
        state.modalForm = {
            'problemName': undefined,
            'scene': undefined,
            'stageNames': undefined,
            'labels': undefined
        }
        currentFaq.value = {}
    }
    const faqRef = ref(null)
    const answerRef = ref(null)
    const currentFaq = ref({})
    function handleConfirmFaq() {
        faqRef.value.validate().then(() => {
            state.addLoading = true
            const api = currentFaq.value.id ? put : post
            api('/solution-ppm/api/v2/built-in-system-ppm/qa/question', state.modalForm)
                .then(data => {
                    if (data.code !== 200) {
                        message.error(data.message)
                        return
                    }
                    message.success(data.message)
                    cancelAdd()
                    getData()
                })
                .finally(() => {
                    state.addLoading = false
                })
        })
    }
    function handlEditFaq(item) {
        let record = cloneDeep(item)
        currentFaq.value = record
        state.addOrEditTitle = '编辑问题'
        Object.assign(state.modalForm, record)
        state.addOrEditFaqVisible = true
    }
    function handleConfirmDelete(id) {
        del(`/solution-ppm/api/v2/built-in-system-ppm/qa/question/${id}`).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            message.success(data.message)
            getData()
        })
    }
    // function handleConfirmAnswer() {
    //     answerRef.value.validate().then(() => {
    //         state.answerLoading = true
    //         post('/solution-ppm/api/v2/built-in-system-ppm/qa/answer', {
    //             ...state.answerForm,
    //             questionId: currentFaq.value.id
    //         })
    //             .then(data => {
    //                 if (data.code !== 200) {
    //                     message.error(data.message)
    //                     return
    //                 }
    //                 message.success(data.message)
    //                 cancelAnswer()
    //                 getData()
    //             })
    //             .finally(() => {
    //                 state.answerLoading = false
    //             })
    //     })
    // }
    function handleConfirmAnswer() {
        answerRef.value.validate().then(async () => {
            state.answerLoading = true
            // 富文本
            const deltaContent = quillEditor.value.getContents()

            const imageUploadPromises = []

            deltaContent.ops.forEach(op => {
                if (op.insert && op.insert.image && op.insert.image.startsWith('data:')) {
                    const localSrc = op.insert.image

                    // 如果是 base64 图片，上传并替换为 URL
                    const file = dataURLtoFile(localSrc, 'image.png') // 将 base64 转换为 File 对象

                    const uploadPromise = uploadFileAPI(file).then(({ data: { fullUrl } }) => {
                        // 替换 op 中的 base64 URL 为服务器返回的 URL
                        op.insert.image = fullUrl
                    })

                    imageUploadPromises.push(uploadPromise)
                }
            })
            // 富文本
            try {
                await Promise.all(imageUploadPromises)
                const params = {
                    answer: JSON.stringify(deltaContent),
                    id: undefined,
                    questionId: undefined
                }
                const api = currentAnswer.value.id ? put : post
                if (currentAnswer.value.id) {
                    params.id = currentAnswer.value.id
                    params.questionId = undefined
                } else {
                    params.questionId = currentFaq.value.id
                    params.id = undefined
                }
                api('/solution-ppm/api/v2/built-in-system-ppm/qa/answer', params)
                    .then(data => {
                        if (data.code !== 200) {
                            message.error(data.message)
                            return
                        }
                        message.success(data.message)
                        cancelAnswer()
                        getData()
                    })
                    .finally(() => {
                        state.answerLoading = false
                    })
            } catch (error) {
                state.answerLoading = false
                console.error('图片上传失败', error)
                return // 终止提交
            }
        })
    }
    function cancelAnswer() {
        state.answerVisible = false
        state.answerForm = {
            answer: undefined
        }
        currentFaq.value = {}
    }
    import { nextTick } from 'vue'
    function handleShowAnswer(item) {
        console.log(item)
        currentFaq.value = item
        state.answerVisible = true
        nextTick(() => {
            initTitle()
        })
    }
    function getBodyStyle() {
        if (state.from) {
            return {
                padding: '24px'
            }
        } else {
            return {
                padding: '0'
            }
        }
    }
    const pageSizeChange = (current, size) => {
        pagination.value.current = current
        pagination.value.pageSize = size
        getData()
    }
    const pageChange = (page, pageSize) => {
        pagination.value.current = page
        pagination.value.pageSize = pageSize
        getData()
    }
    const pagination = ref({
        current: 1,
        pageSize: 20,
        showSizeChanger: true,
        total: 0,
        pageSizeOptions: ['20', '40', '60', '80', '100'],
        showTotal: total =>
            `共 ${total} 个项目 第 ${pagination.value.current}/${Math.ceil(total / pagination.value.pageSize)}页`
    })
    function escapeHtml(str) {
        return str
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#039;')
    }

    function formatText(text, isExpanded) {
        const escaped = escapeHtml(text)
        return isExpanded ? escaped.replace(/\n/g, '<br/>') : escaped.replace(/[\n\r\t]+/g, ' ').replace(/\s+/g, ' ')
    }

    const expandedIndex = ref(null)

    function toggleExpand(index) {
        expandedIndex.value = expandedIndex.value === index ? null : index
    }
    const currentAnswer = ref({})
    //     编辑回答
    function handleEditAnswer(item, index) {
        console.log(item)
        currentAnswer.value = item
        state.answerVisible = true
        nextTick(() => {
            const editor = quillEditor.value
            const content = item.answer

            let delta

            // 尝试解析成 JSON
            if (typeof content === 'string') {
                try {
                    const parsed = JSON.parse(content)
                    // 判断是不是合法的 Delta 格式
                    if (parsed && typeof parsed === 'object' && Array.isArray(parsed.ops)) {
                        delta = parsed
                    }
                } catch (e) {
                    // 不是 JSON，继续走后面的纯文本逻辑
                }
            }

            if (delta) {
                // 是合法 Delta，直接设置
                editor.setContents(delta)
            } else {
                // 清空编辑器内容，插入纯文本
                editor.setText(typeof content === 'string' ? content : String(content || ''))
            }
        })
    }
    //     删除回答
    function handleConfirmDeleteAnswer(id) {
        del(`/solution-ppm/api/v2/built-in-system-ppm/qa/answer/${id}`).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            message.success(data.message)
            getData()
        })
    }
    //     置顶非置顶
    function changeStatus(item) {
        item.loading = true
        console.log(item)
        put('/solution-ppm/api/v2/built-in-system-ppm/qa/answer/display', {
            ...item,
            display: item.display == 1 ? 0 : 1
        })
            .then(data => {
                if (data.code !== 200) {
                    message.error(data.message)
                    return
                }
                message.success(data.message)
                getData()
            })
            .finally(() => {
                item.loading = false
            })
    }
    import { QuillEditor, Quill } from '@vueup/vue-quill'
    import ImageUploader from 'quill-image-uploader'
    import '@vueup/vue-quill/dist/vue-quill.snow.css'
    const titleConfig = [
        { Choice: ' .ql-bold', title: '加粗' },
        { Choice: ' .ql-italic', title: '斜体' },
        { Choice: ' .ql-underline', title: '下划线' },
        { Choice: ' .ql-strike', title: '删除线' },
        { Choice: ' .ql-blockquote', title: '块引用' },
        { Choice: ' .ql-code-block', title: '插入代码' },
        { Choice: ' .ql-size', title: '字体大小' },
        { Choice: ' .ql-size', title: '字体大小' },
        { Choice: ' .ql-color', title: '字体颜色' },
        { Choice: ' .ql-background', title: '字体背景颜色' },
        { Choice: ' .ql-list[value="ordered"]', title: '有序列表' },
        { Choice: ' .ql-list[value="bullet"]', title: '无序列表' },
        { Choice: ' .ql-header[value="1"]', title: '1级标题' },
        { Choice: ' .ql-header[value="2"]', title: '2级标题' },
        { Choice: ' .ql-align', title: '对齐方式' },
        { Choice: ' .ql-clean', title: '清除字体格式' },
        { Choice: ' .ql-image', title: '图像' },
        { Choice: ' .ql-size .ql-picker-item[data-value="small"]', title: '小号' },
        { Choice: ' .ql-size .ql-picker-item[data-value="large"]', title: '大号' },
        { Choice: ' .ql-size .ql-picker-item[data-value="huge"]', title: '超大号' },
        { Choice: ' .ql-size .ql-picker-item:nth-child(2)', title: '标准' },
        { Choice: ' .ql-align .ql-picker-item:first-child', title: '居左对齐' },
        { Choice: ' .ql-align .ql-picker-item[data-value="center"]', title: '居中对齐' },
        { Choice: ' .ql-align .ql-picker-item[data-value="right"]', title: '居右对齐' },
        { Choice: ' .ql-align .ql-picker-item[data-value="justify"]', title: '两端对齐' }
    ]
    // 注册图片上传模块
    Quill.register('modules/imageUploader', ImageUploader)

    // 将本地文件转换为URL
    const getLocalImageURL = file => {
        return new Promise(resolve => {
            const reader = new FileReader()
            reader.onload = e => {
                resolve(e.target.result)
            }
            reader.readAsDataURL(file)
        })
    }

    // 表单数据

    // Quill 编辑器选项
    const editorOption = ref({
        modules: {
            // imageUploader: {
            //     upload: async file => {
            //         const localUrl = await getLocalImageURL(file)
            //         return localUrl // 返回本地图片的 URL 进行预览
            //     }
            // },
            toolbar: [
                ['bold', 'italic', 'underline', 'strike'], // 加粗，斜体，下划线，删除线
                ['blockquote', 'code-block'], // 引用，代码块
                [{ header: 1 }, { header: 2 }], // 标题1，标题2
                [{ list: 'ordered' }, { list: 'bullet' }], // 有序列表，无序列表
                [{ size: ['small', false, 'large', 'huge'] }], // 文字大小
                [{ color: [] }, { background: [] }], // 字体颜色，背景颜色
                [{ align: [] }], // 对齐
                ['clean'], // 清除格式
                ['image'] // 链接，图片，视频
            ]
            // ImageUploader: imageHandler
        }
    })

    // 将 dataURL 转换为 File 对象的辅助函数
    const dataURLtoFile = (dataurl, filename) => {
        const arr = dataurl.split(',')
        const mime = arr[0].match(/:(.*?);/)[1]
        const bstr = atob(arr[1])
        let n = bstr.length
        const u8arr = new Uint8Array(n)
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n)
        }
        return new File([u8arr], filename, { type: mime })
    }

    function initTitle() {
        document.getElementsByClassName('ql-editor')[0].dataset.placeholder = ''
        for (let item of titleConfig) {
            let tip = document.querySelector('.ql-toolbar' + item.Choice)
            if (!tip) continue
            tip.setAttribute('title', item.title)
        }
    }
    const quillEditor = ref(null)
    // 上传API
    const uploadFileAPI = async file => {
        const data = new FormData()
        data.append('file', file)

        return post('/file-storage/api/v1/file/upload', data)
            .then(({ data: { fullUrl } }) => {
                return { data: { fullUrl } }
            })
            .catch(error => {
                console.error('上传图片出错:', error)
                throw error // 抛出错误以供外部处理
            })
    }
    import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html'
    function getHtmlContent(input) {
        if (!input) return ''
        let deltaObj = null
        try {
            const parsed = typeof input === 'string' ? JSON.parse(input) : input
            if (parsed?.ops && Array.isArray(parsed.ops)) {
                deltaObj = parsed
            }
        } catch (e) {}

        if (deltaObj) {
            try {
                const converter = new QuillDeltaToHtmlConverter(deltaObj.ops, {
                    inlineStyles: false
                })
                let html = converter.convert()

                // 预览支持：用原生 <img> 包裹在一个带点击预览功能的 <a> 中
                html = html.replace(/<img[^>]*src="([^"]+)"[^>]*>/g, (match, src) => {
                    return `<img src="${src}" class="previewable-image" title="点击查看图片"/>`
                })

                return html
            } catch (err) {
                console.error('富文本转HTML失败', err)
                return ''
            }
        }

        return String(input).replace(/\n/g, '<br/>')
    }
</script>
<style lang="less" scoped>
    .page_root {
        width: 100%;
        height: 100%;
        overflow: auto;
    }
    .page_root :deep(.@{ant-prefix}-spin-nested-loading),
    .page_root :deep(.@{ant-prefix}-spin-container) {
        height: 100%;
    }
    .page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper) {
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
    }
    .page_root :deep(.@{ant-prefix}-table) {
        flex: auto;
        overflow: auto;
    }
    .table-moreBtn_down {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        width: 100px;
    }

    .table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
        background: #ebf1ff;
    }

    /*  表格树结构样式处理，展开按钮层级增加*/
    :deep(.@{ant-prefix}-table-row-expand-icon) {
        z-index: 1;
    }
    /*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
    :deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 15px !important;
        width: calc(100% - 15px);
    }
    :deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 30px !important;
        width: calc(100% - 30px);
    }
    :deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 45px !important;
        width: calc(100% - 45px);
    }
    :deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 60px !important;
        width: calc(100% - 60px);
    }

    /* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
    :deep(.@{ant-prefix}-transfer-list) {
        height: 100%;
        width: 50%;
    }

    /*
    样式
    */
    .page_root {
        position: relative;
    }
    .body {
        height: 100vh;
        background-color: #fff;
        overflow: hidden;
        position: relative;
    }
    .title {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
    .title-font {
        margin-top: 10px;
        padding-left: 8px;
        font-size: 16px;
        height: 16px;
        line-height: 16px;
        border-left: 4px solid #3875ff;
        display: flex;
        justify-content: space-between;
        margin-bottom: 20px;
        font-weight: 600;
    }
    .gd-template-scroll {
        overflow-y: auto;
        overflow-x: hidden;
        height: calc(100% - 350px);
    }
    .gd-item {
        box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.2);
        margin: 2px;
        margin-bottom: 24px;
        padding-bottom: 16px;
    }
    .gd-item:last-child {
        margin-bottom: 5px;
    }
    .template-item-title {
        width: 100%;
        padding: 16px 24px;
        padding-bottom: 0;
        gap: 24px;
        display: flex;

        background: rgba(56, 117, 255, 0.05);
    }
    .item-top {
        display: flex;
        justify-content: space-between;
    }
    .item-top:first-child {
        border: none;
    }
    .top-left-div {
        display: flex;
        align-items: center;
    }

    .item-name {
        color: #262626;
        letter-spacing: 0;
        display: block; /* 确保其为块级元素 */
        max-width: 100%; /* 确保宽度有限制 */
        font-size: 18px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 600;
        display: flex;
        gap: 8px;
        cursor: pointer;
    }
    .top-right-div {
        flex: 1;
        display: flex;
        align-items: center;
    }

    .bottom-top-item:first-child {
        padding-right: 8px;
    }
    .bottom-top-item:nth-child(n + 2) {
        padding-left: 8px;
    }
    .bottom-top-item:not(:last-child):nth-last-child(n + 2) {
        border-right: 1px solid #d9d9d9;
    }
    .item-icon {
        margin-top: 10px;
        display: flex;
        padding-left: 24px;
        flex-wrap: wrap;
        gap: 8px; /* 可选：让 tag 之间有间距 */
        margin-bottom: 10px;
    }
    :deep(.ant3-tag) {
        margin: 0;
        border-radius: 4px;
        font-size: 14px;
    }
    .item-left {
        width: 90%;
    }
    .add-or-edit-faq :deep(.ant3-form-item-label) {
        width: 80px;
    }
    .no-data-msg {
        position: absolute;
        top: 61%;
        left: 50%;
        transform: translate(-50%, -50%);
        color: #595959;
    }
    .no-data-img {
        width: 66px;
        height: 80px;
        background-image: url('http://10.40.0.33:9001/file-storage/482099304502618112-source.png');
        background-size: cover;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
    .pagination-div {
        position: absolute;
        right: 30px;
        bottom: 200px;
        padding: 10px;
        background: transparent; /* 可选：为背景添加颜色 */
    }
    .answer-item {
        margin-top: 16px;
        border-bottom: 1px solid #d9d9d9;
    }
    .answer-item:last-child {
        border: none;
    }
    .answer-content {
        font-size: 16px;
        justify-content: space-between;
        display: flex;
        padding: 0 24px;
        font-weight: 400;
        color: #262626;
    }
    .answer-content-collapsed {
        display: -webkit-box;
        -webkit-line-clamp: 2; /* 最多显示2行 */
        -webkit-box-orient: vertical;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: normal; /* 允许自动换行，但不会按 \n 分行 */
    }
    .count {
        color: #3875ff;
        //position: relative;
    }
    .count-under {
        width: 100%;
        height: 4px;
        opacity: 0.54;
        background-image: linear-gradient(180deg, #8caeff 0%, rgba(140, 174, 255, 0) 100%);
        position: relative;
        //left: 50%;
        //transform: translateX(-50%);
        bottom: 5px;
        right: -0.5px;
    }
    :deep(.ql-toolbar) {
        background: #fafafa;
        border: 1px solid #d9d9d9;
        border-radius: 2px 2px 0 0;
    }
    :deep(.ql-blank) {
        min-height: 110px;
        background: #ffffff;
    }
    :deep(.ql-editor) {
        min-height: 110px;
        background: #ffffff;
    }
    .add-or-edit-faq :deep(.ql-snow .ql-editor) img {
        width: 200px;
    }
    .answer-preview {
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 16;
        overflow: hidden;
        white-space: normal;
        line-height: 1.5em;
        word-break: break-word;
        max-height: 15em; /* 10 行 × 1.5em */
    }

    .answer-preview.expanded {
        -webkit-line-clamp: unset;
        max-height: none;
    }
    .icon-main {
        display: flex;
        justify-content: space-between;
        align-items: center;
        background: rgba(56, 117, 255, 0.05);
        gap: 24px;
        padding-right: 24px;
    }
    .item-bottom {
        display: flex;
        justify-content: end;
        height: 16px;
        line-height: 16px;
        flex-shrink: 0; /* 防止压缩 */
    }
    .bottom-top-msg {
        font-size: 12px;
        color: #262626;
        letter-spacing: 0;
        line-height: 17px;
        font-weight: 500;
    }
    .bottom-top-title {
        font-size: 12px;
        color: #595959;
        letter-spacing: 0;
        line-height: 17px;
        font-weight: 400;
    }
    .btn-title {
        display: flex;
        padding: 0 24px;
        margin-bottom: 8px;
        justify-content: space-between;
    }
    .btn-left {
        display: flex;
        align-items: center;
        font-size: 16px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 600;
        gap: 8px;
    }
    .btn-img {
        width: 16px;
        height: 16px;
        background-size: cover;
        background-image: url('http://10.40.0.33:9001/file-storage/504241932385871872-source.png');
    }
    .line {
        height: 16px;
        width: 1px;
        background: #3875ff;
    }
</style>
